<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import type { ArticleVO } from '@/types'
import { articleApi } from '@/api/article'
import { MdPreview } from 'md-editor-v3'
import 'md-editor-v3/lib/style.css'
import CommentSection from '@/components/comment/CommentSection.vue'
import { useAuthStore } from '@/store/modules/auth'

const route = useRoute()
const router = useRouter()
const article = ref<ArticleVO | null>(null)

// 添加目录相关的逻辑
const headers = ref<{ level: number; text: string; id: string }[]>([])

// 生成目录
const generateToc = () => {
  setTimeout(() => {
    const articleContent = document.querySelector('.md-editor-preview')
    if (!articleContent) return

    const headings = articleContent.querySelectorAll('h1, h2, h3, h4, h5, h6')
    headers.value = Array.from(headings).map((heading, index) => {
      const id = `heading-${index}-${heading.textContent?.toLowerCase().replace(/\s+/g, '-')}`
      heading.id = id

      return {
        level: parseInt(heading.tagName[1]),
        text: heading.textContent || '',
        id,
      }
    })
  }, 500)
}

// 返回
const goBack = () => {
  router.back()
}

onMounted(async () => {
  try {
    const response = await articleApi.getArticleById(Number(route.params.id))
    if (response.code === 200) {
      article.value = response.data
      // 在文章内容加载后生成目录
      generateToc()
    } else {
      console.error('获取文章详情失败:', response.msg)
    }
  } catch (error) {
    console.error('获取文章详情失败:', error)
  }
})

const handleLike = async () => {
  if (!article.value) return

  try {
    const response = await articleApi.setLike(article.value.id, 1)
    if (response.code === 200 && response.data) {
      article.value.isLiked = 1
      article.value.liked++
    }
  } catch (error) {
    console.error('点赞失败:', error)
  }
}

// 点击目录项滚动到对应位置
const scrollToHeader = (id: string) => {
  const element = document.getElementById(id)
  if (element) {
    // 计算目标位置，考虑固定导航栏的高度
    const offset = 80 // 导航栏高度 + 一些额外空间
    const elementPosition = element.getBoundingClientRect().top + window.pageYOffset
    const offsetPosition = elementPosition - offset

    window.scrollTo({
      top: offsetPosition,
      behavior: 'smooth',
    })
  }
}

// 获取 auth store 实例
const authStore = useAuthStore()
</script>

<template>
  <!-- 面包屑导航 -->
  <nav class="fixed top-[60px] left-0 w-full z-20">
    <div class="flex items-center h-12 text-sm">
      <button
        @click="goBack"
        class="group flex items-center text-gray-600 hover:text-blue-600 transition-colors pl-6"
      >
        <svg
          xmlns="http://www.w3.org/2000/svg"
          class="h-5 w-5 mr-1.5 transition-transform group-hover:-translate-x-0.5"
          viewBox="0 0 20 20"
          fill="currentColor"
        >
          <path
            fill-rule="evenodd"
            d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z"
            clip-rule="evenodd"
          />
        </svg>
        返回
      </button>
      <span class="text-gray-400 mx-2">/</span>
      <span class="text-gray-900">文章详情</span>
    </div>
  </nav>

  <!-- 主容器添加上边距以避免与固定导航重叠 -->
  <div class="relative max-w-6xl mx-auto px-4 pt-[72px] pb-8">
    <div class="flex">
      <!-- 左侧文章内容 -->
      <div class="flex-1 max-w-4xl">
        <!-- 文章内容 -->
        <div v-if="article" class="bg-white rounded-lg shadow-sm p-6 md:p-8">
          <h1 class="text-3xl font-bold text-gray-900 mb-6">{{ article.articleTitle }}</h1>

          <!-- 作者信息和文章元数据 -->
          <div
            class="flex flex-col sm:flex-row sm:items-center sm:justify-between mb-8 pb-6 border-b"
          >
            <!-- 作者信息 -->
            <div class="flex items-center space-x-3 mb-4 sm:mb-0">
              <img
                :src="article.authorAvatar || '/default-avatar.png'"
                :alt="article.authorNickName"
                class="w-10 h-10 rounded-full object-cover"
                @error="
                  (e: Event) => {
                    const target = e.target as HTMLImageElement
                    if (target) target.src = '/default-avatar.png'
                  }
                "
              />
              <div>
                <div class="font-medium text-gray-900">
                  {{ article.authorNickName || '匿名用户' }}
                </div>
                <div class="text-sm text-gray-500">{{ article.createTime }}</div>
              </div>
            </div>

            <!-- 文章数据 -->
            <div class="flex items-center space-x-6">
              <span class="flex items-center text-sm text-gray-500">
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  class="h-5 w-5 mr-1"
                  viewBox="0 0 20 20"
                  fill="currentColor"
                >
                  <path
                    d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z"
                  />
                </svg>
                {{ article.liked }} 点赞
              </span>
              <span class="flex items-center text-sm text-gray-500">
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  class="h-5 w-5 mr-1"
                  viewBox="0 0 20 20"
                  fill="currentColor"
                >
                  <path
                    fill-rule="evenodd"
                    d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z"
                    clip-rule="evenodd"
                  />
                </svg>
                {{ new Date(article.createTime).toLocaleDateString() }}
              </span>
            </div>
          </div>

          <!-- 文章内容 -->
          <div class="prose max-w-none" id="article-content">
            <MdPreview :modelValue="article.articleContent" />
          </div>

          <!-- 点赞按钮 -->
          <div class="mt-8 flex justify-center">
            <template v-if="authStore.user">
              <button
                v-if="article.isLiked === 0"
                @click="handleLike"
                class="inline-flex items-center px-4 py-2 rounded-full text-sm font-medium text-blue-600 bg-blue-50 hover:bg-blue-100 transition-colors"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  class="h-5 w-5 mr-2"
                  viewBox="0 0 20 20"
                  fill="currentColor"
                >
                  <path
                    d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z"
                  />
                </svg>
                点赞
              </button>
              <button
                v-else
                disabled
                class="inline-flex items-center px-4 py-2 rounded-full text-sm font-medium text-gray-400 bg-gray-100 cursor-not-allowed"
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  class="h-5 w-5 mr-2"
                  viewBox="0 0 20 20"
                  fill="currentColor"
                >
                  <path
                    d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z"
                  />
                </svg>
                已点赞
              </button>
            </template>
          </div>
          <CommentSection :article-id="article.id" class="relative z-10" />
        </div>

        <!-- 加载状态 -->
        <div v-else class="flex justify-center items-center py-12">
          <div
            class="animate-spin rounded-full h-8 w-8 border-2 border-blue-600 border-t-transparent"
          ></div>
        </div>
      </div>

      <!-- 右侧目录 -->
      <div class="hidden lg:block w-64 ml-8">
        <div class="sticky top-20">
          <div
            v-if="headers.length > 0"
            class="bg-white rounded-lg shadow-md p-4 border-2 border-gray-100 hover:border-blue-100 transition-all duration-300"
          >
            <h3 class="text-lg font-semibold mb-4 pb-2 border-b border-gray-100">目录</h3>
            <nav class="toc-nav">
              <ul class="space-y-1.5">
                <li
                  v-for="header in headers"
                  :key="header.id"
                  class="toc-item"
                  :class="{
                    'ml-3': header.level > 1,
                    'ml-6': header.level > 2,
                    'ml-9': header.level > 3,
                  }"
                >
                  <div class="flex items-center relative" :class="{ 'has-line': header.level > 1 }">
                    <span v-if="header.level > 1" class="tree-node"></span>
                    <a
                      @click="scrollToHeader(header.id)"
                      class="toc-link text-sm text-gray-600 hover:text-blue-600 cursor-pointer truncate py-1 pl-2"
                      :class="{ 'font-medium': header.level === 1 }"
                      :title="header.text"
                    >
                      {{ header.text }}
                    </a>
                  </div>
                </li>
              </ul>
            </nav>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.prose {
  @apply text-gray-900;
}

.prose img {
  @apply rounded-lg mx-auto;
  max-width: 100%;
  height: auto;
}

.prose pre {
  @apply bg-gray-100 p-4 rounded-lg overflow-x-auto;
}

.prose code {
  @apply bg-gray-100 px-1 rounded;
}

.prose blockquote {
  @apply border-l-4 border-gray-200 pl-4 italic;
}

.prose a {
  @apply text-blue-600 hover:text-blue-700 underline;
}

.prose h1,
.prose h2,
.prose h3,
.prose h4,
.prose h5,
.prose h6 {
  @apply font-bold text-gray-900 mt-8 mb-4;
}

.prose p {
  @apply mb-4 leading-relaxed;
}

.prose ul,
.prose ol {
  @apply mb-4 pl-6;
}

.prose li {
  @apply mb-2;
}

/* 目录容器样式 */
.toc-nav {
  @apply relative;
  max-height: calc(100vh - 280px); /* 调整最大高度 */
  overflow-y: auto;
  padding-right: 8px;
}

/* 目录项样式 */
.toc-item {
  @apply relative;
}

/* 树状连接线样式 */
.tree-node {
  @apply absolute w-2 h-2 rounded-full bg-gray-300;
  left: -8px;
  top: 50%;
  transform: translateY(-50%);
  transition: all 0.2s ease;
}

.tree-node::before {
  content: '';
  @apply absolute h-full w-px bg-gray-200;
  left: 50%;
  top: -100%;
  transform: translateX(-50%);
}

.has-line::before {
  content: '';
  @apply absolute w-2 h-px bg-gray-200;
  left: -8px;
  top: 50%;
  transform: translateY(-50%);
}

/* 悬停效果 */
.toc-link {
  @apply relative transition-all duration-200 block rounded;
  padding: 4px 8px;
}

.toc-link:hover {
  @apply bg-blue-50;
}

.toc-item:hover > div > .tree-node {
  @apply bg-blue-500 scale-110;
}

.toc-item:hover > div.has-line::before {
  @apply bg-blue-200;
}

/* 滚动条样式 */
.toc-nav::-webkit-scrollbar {
  @apply w-1.5;
}

.toc-nav::-webkit-scrollbar-track {
  @apply bg-gray-50 rounded-full;
}

.toc-nav::-webkit-scrollbar-thumb {
  @apply bg-gray-300 rounded-full;
}

.toc-nav::-webkit-scrollbar-thumb:hover {
  @apply bg-gray-400;
}

/* 修改目录卡片容器样式 */
.sticky {
  position: sticky;
  top: 80px; /* 调整顶部距离 */
  max-height: calc(100vh - 100px); /* 限制整个卡片的最大高度 */
  margin-bottom: 2rem; /* 添加底部边距 */
}

/* 修改目录卡片样式 */
.shadow-md {
  box-shadow:
    0 4px 6px -1px rgba(0, 0, 0, 0.1),
    0 2px 4px -1px rgba(0, 0, 0, 0.06);
  height: fit-content; /* 让卡片高度适应内容 */
}

/* 移除之前的底部padding */
.sticky {
  padding-bottom: 0; /* 移除之前添加的底部padding */
}

/* 确保目录项容器紧凑 */
.space-y-1\.5 > * + * {
  margin-top: 0.375rem; /* 减小目录项之间的间距 */
}

/* 添加滚动偏移量的全局样式 */
:deep(.md-editor-preview h1),
:deep(.md-editor-preview h2),
:deep(.md-editor-preview h3),
:deep(.md-editor-preview h4),
:deep(.md-editor-preview h5),
:deep(.md-editor-preview h6) {
  scroll-margin-top: 80px;
}
</style>
